import { useEffect, useRef, useState } from 'react'
import classNames from 'classnames'
import { Input, InputProps, InputRef, Popover, PopoverProps, Typography } from 'antd'
import { CloseCircleFilled, EyeInvisibleOutlined, EyeOutlined, SearchOutlined } from '@ant-design/icons'

import { apiGetEventList, IEventTemplateEnableRes } from './api'
import { getStatusGroupName, getStatusName } from './utils'
import styles from './styles.module.less'

type PopoverComponentProps = Omit<PopoverProps, 'content'>

type InputComponentProps = Omit<InputProps, 'value'>

interface IEventSelectProps {
  popoverProps?: PopoverComponentProps
  inputProps?: InputComponentProps
  onChange?: (value?: IEventTemplateEnableRes) => void
  value?: IEventTemplateEnableRes
  outsideEventList?: IEventTemplateEnableRes[]
}

export const EventSelect = (props: IEventSelectProps) => {
  const { popoverProps, inputProps, onChange, value } = props
  const [showValue, setShowValue] = useState<string>('')
  const [eventList, setEventList] = useState<IEventTemplateEnableRes[]>([])
  const [allEventList, setAllEventList] = useState<IEventTemplateEnableRes[]>([])
  const [open, setOpen] = useState<boolean>(false)
  const inputRef = useRef<InputRef>(null)
  const [searchText, setSearchText] = useState<string>('')
  const composingRef = useRef<boolean>(false)
  const debounceRef = useRef<number | undefined>(undefined)

  const messageTypeClassNameMap = {
    1: styles.content_item_primary,
    2: styles.content_item_success,
    3: styles.content_item_danger,
  }

  const getEventList = async () => {
    const res = props?.outsideEventList ? props?.outsideEventList : await apiGetEventList()
    const list = res || []
    setAllEventList(list)
    setEventList(list)
    setSearchText('')
  }

  const handleChange = (value?: IEventTemplateEnableRes) => {
    onChange?.(value)
    setOpen(false)
  }

  useEffect(() => {
    getEventList()
  }, [props.outsideEventList])

  // 轻量模糊匹配评分：按子序列匹配并给予邻接加分；对于中文两字等短语，支持逆序匹配
  const fuzzyScore = (text: string, query: string): number => {
    const t = (text || '').toLowerCase()
    const q = (query || '').toLowerCase()
    if (!q) return -1
    const scoreSeq = (qq: string): number => {
      let score = 0
      let ti = 0
      let last = -1
      for (let i = 0; i < qq.length; i++) {
        const ch = qq[i]
        const found = t.indexOf(ch, ti)
        if (found === -1) return -1
        score += 1
        if (found === last + 1) score += 0.5
        last = found
        ti = found + 1
      }
      const startBonus = t.indexOf(qq[0]) <= 2 ? 0.3 : 0
      return score / qq.length + startBonus
    }
    const normal = scoreSeq(q)
    if (normal >= 0) return normal
    // 逆序尝试：处理中文两字等短语在文本中出现为“收签”等顺序的情况
    const reversed = scoreSeq(q.split('').reverse().join(''))
    return reversed
  }

  useEffect(() => {
    setShowValue(value?.templateCn || '')
  }, [value])

  const filterAndRank = (kw: string) => {
    const q = kw.trim().toLowerCase()
    if (!q) {
      setEventList(allEventList)
      return
    }
    const tokens = q.split(/[\s\u3000,，、;；]+/).filter(Boolean)
    const ranked = allEventList
      .map(d => {
        const cn = (d.templateCn || '').toLowerCase()
        const en = (d.templateEn || '').toLowerCase()
        let total = 0
        for (const token of tokens) {
          const s = Math.max(fuzzyScore(cn, token), fuzzyScore(en, token))
          if (s < 0) return null
          total += s
        }
        return { item: d, score: total }
      })
      .filter(Boolean)
      .sort((a, b) => b!.score - a!.score)
      .map(r => r!.item)
    setEventList(ranked)
  }

  useEffect(() => {
    if (debounceRef.current) window.clearTimeout(debounceRef.current)
    debounceRef.current = window.setTimeout(() => {
      filterAndRank(searchText)
    }, 150)
    return () => {
      if (debounceRef.current) window.clearTimeout(debounceRef.current)
    }
  }, [searchText, allEventList])

  return (
    <Popover
      {...popoverProps}
      arrow={false}
      placement="bottomLeft"
      trigger="click"
      open={open}
      onOpenChange={v => setOpen(v)}
      content={
        <div className={styles.content}>
          <Typography.Title level={5}>选择轨迹模版</Typography.Title>
          <Input
            className={styles.search}
            placeholder="搜索轨迹模版名称"
            prefix={<SearchOutlined />}
            onFocus={() => setOpen(true)}
            value={searchText}
            onChange={e => setSearchText(e.target.value)}
            onCompositionStart={() => {
              composingRef.current = true
            }}
            onCompositionEnd={e => {
              composingRef.current = false
              setSearchText(e.currentTarget.value)
            }}
          />
          {eventList?.map(d => (
            <div
              className={classNames(styles.content_item, messageTypeClassNameMap[d.messageType as 1 | 2 | 3])}
              key={d.eventTemplateId}
              onClick={() => handleChange(d)}
            >
              <div className={styles.content_item_left}>
                <Typography.Title level={5} className={styles.item_title}>
                  {d.templateCn}
                </Typography.Title>
                <Typography.Text className={styles.item_sub}>{d.templateEn}</Typography.Text>
                <div className={styles.item_status_row}>
                  <span
                    className={`${styles.tag} ${Number(d.statusGroup) === 2 ? styles.tag_warning : styles.tag_primary}`}
                  >
                    {getStatusGroupName(Number(d.statusGroup))}
                  </span>
                  <span className={styles.status_text}>{getStatusName(d.status)}</span>
                </div>
              </div>
              <div className={styles.content_item_right}>
                {d.visibleFlag ? (
                  <EyeOutlined
                    style={{
                      color: '#1677ff',
                    }}
                  />
                ) : (
                  <EyeInvisibleOutlined />
                )}
              </div>
            </div>
          ))}
        </div>
      }
    >
      <Input
        {...inputProps}
        readOnly
        ref={inputRef}
        value={showValue}
        allowClear={false}
        placeholder="请选择轨迹模版"
        suffix={
          showValue ? (
            <span className="ant-input-clear-icon" onClick={e => e.stopPropagation()}>
              <CloseCircleFilled
                onClick={() => {
                  onChange?.(undefined)
                  inputRef.current?.focus()
                }}
              />
            </span>
          ) : (
            <></>
          )
        }
      />
    </Popover>
  )
}
